#pragma once
#include <string>
#include "Util.hpp"
#define HEAD_SEP "\r\n"
#define BUFFER_SIZE 1024
#include <sys/types.h>
#include <sys/socket.h>
#include "Util.hpp"
#include <vector>
#include <jsoncpp/json/json.h>
#include <cstring>

namespace my_protocol
{
// 协议的分隔符
#define SEP " "
#define SEP_LEN strlen(SEP)
    // #define USER 1

    // 读取数据
    int ReadPackage(int sock, std::string &inBuff, std::string *package)
    {
        // 也可以使用 read 函数
        char buff[BUFFER_SIZE];
        int n = recv(sock, buff, sizeof(buff) - 1, 0);
        // std::cout << "n = " << n << std::endl;
        if (n < 0)
            return -1; // 表示读取失败
        else if (n == 0)
            return 0; // 需要继续读取

        buff[n] = '\0'; // 5\r\n1 + 1
        inBuff += buff;

        // 判断inBuff 中是否存在完整的数据包(报头\r\n有效载荷)
        int pos = inBuff.find(HEAD_SEP);
        if (pos == std::string::npos)
        {
            return -1;
        }
        std::string strlen = inBuff.substr(0, pos); // 有效载荷的长度
        int len = sizeof("\r\n") - 1;
        int packLen = strlen.size() + len + Util::StrToInt(strlen); // 报头 + 分隔符 + 有效载荷的总长度
        if (inBuff.size() < packLen)
            return -1; // 不完整

        *package = inBuff.substr(0, packLen); // 完整的数据包
        inBuff.erase(0, packLen);             // 从缓冲区中取走字符串
        return Util::StrToInt(strlen);
    }
    // 添加报头
    void AddHeader(std::string &str)
    {
        // 先计算出长度
        size_t len = str.size();
        std::string strlen = Util::IntToStr(len);

        // 再进行拼接
        str = strlen + HEAD_SEP + str;
    }

    // 移除报头
    void RemoveHeader(std::string &str, size_t len)
    {
        // len表示有效载荷的长度
        str = str.substr(str.size() - len);
    }
    class Request
    {
    public:
        Request(int x = 0, int y = 0, char op = '+')
            : _x(x), _y(y), _op(op)
        {
        }

        // 序列化
        bool Serialization(std::string *outStr)
        {
            *outStr = ""; // 清空
#ifdef USER

            std::string left = Util::IntToStr(_x);
            std::string right = Util::IntToStr(_y);
            *outStr = left + SEP + _op + SEP + right;
#else
            // 使用 Json
            Json::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["op"] = _op;

            Json::FastWriter writer;
            *outStr = writer.write(root);
#endif
            std::cout << "序列化完成：" << *outStr << std::endl;

            return true;
        }

        // 反序列化
        bool Deserialization(const std::string &inStr)
        {
#ifdef USER
            std::vector<std::string> result;
            Util::StringSplit(inStr, SEP, &result);

            // 协议规定：只允许存在两个操作数和一个运算符
            if (result.size() != 3)
                return false;

            // 规定：运算符只能为一个字符
            if (result[1].size() != 1)
                return false;

            _x = Util::StrToInt(result[0]);
            _y = Util::StrToInt(result[2]);
            _op = result[1][0];
#else
            // 使用Json
            Json::Value root;
            Json::Reader reader;
            reader.parse(inStr, root);
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _op = root["op"].asInt();
#endif

            return true;
        }

        ~Request()
        {
        }

    public:
        int _x;
        int _y;
        char _op;
    };

    class Response
    {
    public:
        Response(int result = 0, int code = 0)
            : _result(result), _code(code)
        {
        }

        // 序列化
        bool Serialization(std::string *outStr)
        {
            *outStr = ""; // 清空
#ifdef USER
            std::string left = Util::IntToStr(_result);
            std::string right = Util::IntToStr(_code);
            *outStr = left + SEP + right;
#else
            Json::Value root;
            root["_result"] = _result;
            root["_code"] = _code;
            Json::FastWriter writer;
            *outStr = writer.write(root);
#endif
            std::cout << "序列化完成：" << *outStr << std::endl;
            return true;
        }
        // 反序列化
        bool Deserialization(const std::string &inStr)
        {
#ifdef USER
            std::vector<std::string> result;
            Util::StringSplit(inStr, SEP, &result);

            if (result.size() != 2)
                return false;

            _result = Util::StrToInt(result[0]);
            _code = Util::StrToInt(result[1]);
#else
            // 使用Json
            Json::Value root;
            Json::Reader reader;
            reader.parse(inStr, root);

            _result = root["_result"].asInt();
            _code = root["_code"].asInt();
#endif

            return true;
        }

        ~Response()
        {
        }

    public:
        int _result; // 结果
        int _code;   // 错误码
    };
}